<?php
/*
 * @Description: 请求支付类
 * @Author: QianLong
 * @Date: 2019-09-27 16:34:02
 * @LastEditors    : QianLong
 * @LastEditTime   : 2022-06-09 15:47:11
 */

namespace app\common;

use app\common\service\Wxpay;
use app\common\service\Alipay;
use app\lib\exception\ApiException;
use Ecmpay\Ecmpay\Ecmpay;

class requestPay
{
    /**
     * 请求支付
     * @param string $subject 订单标题
     * @param string $money 订单金额
     * @param string $order_sn 订单编号（唯一）
     * @param string $payType 支付类型
     * @param string $openid 微信openid
     * @param string $return_url 跳转地址
     * @param string $notify_url 异步通知地址
     * @return void
     * @author QianLong <87498106@qq.com>
     * @date 2021-04-15 10:46:09
     * @editAuthor QianLong <87498106@qq.com>
     * @editDescription 
     * @editDate 2021-04-15 10:46:09
     */
    public static function doPay($subject, $money, $order_sn, string $payType, $openid = '', $return_url = '', $notify_url = '')
    {
        if (!in_array($payType, ['wx_app_pay', 'wx_mini_app_pay', 'wx_h5_pay', 'alipay_app', 'balance', 'wx_qr_pay', 'alipay_pc'])) {
            throw new ApiException("支付方式当前仅限：wx_app_pay(微信APP支付)、wx_mini_app_pay(微信小程序支付)、wx_h5_pay(微信H5支付)、wx_qr_pay(微信扫码支付)、alipay_app(支付宝APP支付)、balance(平台余额支付)、alipay_pc(支付宝PC支付)");
        }
        $order['subject'] = $subject;
        $order['total_amount'] = $money;
        $order['out_trade_no'] = $order_sn;
        $order['openid'] = $openid;
        if ($payType == 'balance') {
            return self::doBalance($order);
        }
        $type = explode('_', $payType);
        if ($type[0] == 'wx') {
            if (empty($notify_url)) {
                $paySetting = (new RedisCache())::getSysPaySetting('wxpay');
                $notify_url = $paySetting['notify_url'];
            }
        } elseif ($type[0] == 'alipay') {
            if (empty($notify_url)) {
                $paySetting = (new RedisCache())::getSysPaySetting('alipay');
                $notify_url = $paySetting['notify_url'];
            }
        }
        $platformSetting = (new RedisCache())::getSysPaymentSetting();
        if (!isset($platformSetting['pay_platform']) || $platformSetting['pay_platform'] != 'ecmpay') {
            // 直连支付
            if ($payType == 'wx_app_pay') {
                return (new Wxpay)->payForApp($order, $notify_url);
            } elseif ($payType == 'wx_mini_app_pay' || $payType == 'wx_h5_pay') {
                return (new Wxpay)->payForJsapi($order, $notify_url);
            } elseif ($payType == 'wx_qr_pay') {
                return (new Wxpay)->payForQrcode($order, $notify_url);
            } elseif ($payType == 'alipay_app') {
                return (new Alipay)->payForApp($order, '', $notify_url);
            } elseif ($payType == 'alipay_pc') {
                return (new Alipay)->payForPc($order, $return_url,$notify_url);
            }
        } else {
            // 聚合支付
            $order['trade_no'] = $order_sn;
            Ecmpay::init(['app_id' => $paySetting['app_id'], 'auth_app_id' => $paySetting['auth_app_id'], 'appSecret' => $paySetting['app_secret']]);
            if ($payType == 'wx_app_pay') {
                return Ecmpay::wxpayForApp($order, $notify_url);
            } elseif ($payType == 'wx_mini_app_pay') {
                return Ecmpay::wxpayForJsApi($order, $notify_url);
            } elseif ($payType == 'wx_h5_pay') {
                return Ecmpay::wxpayForH5($order, $notify_url);
            } elseif ($payType == 'wx_qr_pay') {
                return Ecmpay::wxpayForPaymentCode($order, $notify_url);
            } elseif ($payType == 'alipay_app') {
                return Ecmpay::alipayForApp($order, $notify_url);
            } elseif ($payType == 'alipay_pc') {
                return Ecmpay::alipayForPc($order, $return_url, $notify_url);
            }
        }
    }
    private static function doBalance($order)
    {
        // 待添加余额支付逻辑
    }
    /**
     * 发起退款请求
     * @param string $serialNo 支付平台流水号
     * @param string $refund 退款金额
     * @param string $total_amount 订单总金额
     * @param string $order_sn 退款单号（唯一）
     * @param string $reason 退款原因
     * @param string $openid 微信openid
     * @param string $payType 支付类型
     * @param string $notify_url 通知地址
     * @return void
     * @author QianLong <87498106@qq.com>
     * @date 2021-04-14 17:26:08
     * @editAuthor QianLong <87498106@qq.com>
     * @editDescription 
     * @editDate 2021-04-14 17:26:08
     */
    public static function doRefund($serialNo, $refund, $total_amount, $order_sn, $reason = '', $openid = '', $payType = '', $notify_url = '')
    {
        $order['out_trade_no'] = $serialNo;
        $order['trade_no'] = $serialNo;
        $order['refund'] = $refund;
        $order['refund_amount'] = $refund;
        $order['total_amount'] = $total_amount;
        $order['out_refund_no'] = $order_sn;
        $order['out_request_no'] = $order_sn;
        $order['openid'] = $openid;
        $order['reason'] = $reason;
        if ($payType == 'balance') {
            return self::doBalanceRefund($order);
        }
        $platformSetting = (new RedisCache())::getSysPaymentSetting();
        if (!isset($platformSetting['pay_platform']) || $platformSetting['pay_platform'] != 'ecmpay') {
            // 直连支付
            if ($payType == 'wxpay') {
                return (new Wxpay)->refund($order, $notify_url);
            } elseif ($payType == 'alipay') {
                return (new Alipay)->refund($order);
            }
        } else {
            // 聚合支付
            if ($payType == 'wxpay') {
                $paySetting = (new RedisCache())::getSysPaySetting('wxpay');
                if ($paySetting['mch_type'] == 'submch') {
                    $order['sub_mchid'] = $paySetting['mch_id'];
                } elseif ($paySetting['mch_type'] == 'mch') {
                    $order['mch_no'] = $paySetting['mch_id'];
                }
            } elseif ($payType == 'alipay') {
                $paySetting = (new RedisCache())::getSysPaySetting('alipay');
            }
            Ecmpay::init(['app_id' => $paySetting['app_id'], 'auth_app_id' => $paySetting['auth_app_id'], 'appSecret' => $paySetting['app_secret']]);
            return Ecmpay::refund($order, $payType);
        }
    }
    private static function doBalanceRefund($order)
    {
        // 待添加余额支付退款逻辑
    }
    /**
     * 提现转帐
     * @param string $note 提现标题
     * @param string $order_sn 提现单号
     * @param string $amount 提现金额
     * @param string $account 提现账号（微信为openid）
     * @param string $name 提现账号对应实名姓名
     * @param string $payType 支付方式
     * @param string $isRedPacket 是否是红包（支付宝有效）
     * @return void
     * @author QianLong <87498106@qq.com>
     * @date 2021-05-07 12:01:33
     * @editAuthor QianLong <87498106@qq.com>
     * @editDescription 
     * @editDate 2021-05-07 12:01:33
     */
    public static function doTransfer($note, $order_sn, $amount, $account, $name, $payType = '', $isRedPacket = false)
    {
        $order['out_trade_no'] = $order_sn;
        $order['desc'] = $note;
        $order['subject'] = $note;
        $order['amount'] = $amount;
        $order['total_amount'] = $amount;
        $order['openid'] = $account;
        $order['alipay'] = $account;
        $order['check_name'] = 'FORCE_CHECK';
        $order['re_user_name'] = $name;
        $order['name'] = $name;
        $order['trade_no'] = $order_sn;
        $order['trans_amount'] = $amount;
        $order['identity'] = $account;
        $order['identity_type'] = 'ALIPAY_LOGON_ID';
        $order['payer_show_name'] = '千龙CMS';
        $order['client_ip'] = get_client_ip();
        $platformSetting = (new RedisCache())::getSysPaymentSetting();
        if (!isset($platformSetting['pay_platform']) || $platformSetting['pay_platform'] != 'ecmpay') {
            // 直连支付
            if ($payType == 'wxpay') {
                return (new Wxpay)->mchPay($order);
            } elseif ($payType == 'alipay') {
                return (new Alipay)->transfer($order, '', $isRedPacket);
            } elseif ($payType == 'bankcard') {
                // 待处理
            }
        } else {
            // 聚合支付
            if ($payType == 'wxpay') {
                $paySetting = (new RedisCache())::getSysPaySetting('wxpay');
                $order['mch_no'] = $paySetting['mch_no'];
            } elseif ($payType == 'alipay') {
                $paySetting = (new RedisCache())::getSysPaySetting('alipay');
            }
            Ecmpay::init(['app_id' => $paySetting['app_id'], 'auth_app_id' => $paySetting['auth_app_id'], 'appSecret' => $paySetting['app_secret']]);
            return Ecmpay::transfer($order, $payType);
        }
    }
}
